<?php
class Question {
    private $conn;
    private $auth;

    public function __construct(PDO $conn, Auth $auth) {
        $this->conn = $conn;
        $this->auth = $auth;
    }

    public function add(): void {
        try {
            $userId = $this->auth->getUserId();
            if ($userId === 0) {
                throw new Exception("请先登录", 401);
            }

            $input = json_decode(file_get_contents('php://input'), true);
            if ($input === null) {
                throw new Exception("无效的JSON数据", 400);
            }

            // 验证必填字段
            if (empty($input['q_id'])) {
                throw new Exception("缺少问卷ID", 400);
            }
            if (empty($input['type']) || !in_array($input['type'], ['radio', 'check', 'text', 'textarea', 'textgroup'])) {
                throw new Exception("问题类型无效，必须是radio(单选)/check(多选)/text(填空)/textarea(文本域)/textgroup(文本组)", 400);
            }
            if (empty($input['content'])) {
                throw new Exception("问题内容不能为空", 400);
            }

            $questionnaireId = $input['q_id'];

            // 检查问卷是否存在且属于当前用户
            $stmt = $this->conn->prepare("
                SELECT id FROM questionnaires 
                WHERE id = :id AND user_id = :user_id
                LIMIT 1
            ");
            $stmt->execute([
                ':id' => $questionnaireId,
                ':user_id' => $userId
            ]);
            if (!$stmt->fetch()) {
                throw new Exception("问卷不存在或无权操作", 404);
            }

            // 处理不同类型的问题选项
            $options = null;
            if ($input['type'] === 'textgroup') {
                // textgroup类型必须提供options
                if (empty($input['options'])) {
                    throw new Exception("文本组类型必须提供字段定义", 400);
                }
                
                // 处理textgroup的options格式
                if (is_string($input['options'])) {
                    $optionsArray = json_decode($input['options'], true);
                    if ($optionsArray === null) {
                        throw new Exception("文本组字段定义格式无效", 400);
                    }
                    $input['options'] = $optionsArray;
                }
                
                if (!is_array($input['options'])) {
                    throw new Exception("文本组字段定义必须是数组或有效的JSON字符串", 400);
                }
                
                // 验证每个字段是否有label
                foreach ($input['options'] as $field) {
                    if (empty($field['label'])) {
                        throw new Exception("文本组字段必须包含label属性", 400);
                    }
                }
                
                $options = json_encode($input['options'], JSON_UNESCAPED_UNICODE);
            } elseif ($input['type'] !== 'text' && $input['type'] !== 'textarea') {
                // 选择题必须提供选项
                if (empty($input['options'])) {
                    throw new Exception("选择题必须提供选项", 400);
                }
                
                // 处理options格式（支持数组或JSON字符串）
                if (is_string($input['options'])) {
                    $optionsArray = json_decode($input['options'], true);
                    if ($optionsArray === null) {
                        throw new Exception("选项格式无效", 400);
                    }
                    $input['options'] = $optionsArray;
                }
                
                if (!is_array($input['options'])) {
                    throw new Exception("选项必须是数组或有效的JSON字符串", 400);
                }
                
                // 如果已经是键值对格式（如 {"A":"选项1"}），则直接使用
                if (array_keys($input['options']) !== range(0, count($input['options']) - 1)) {
                    $options = json_encode($input['options'], JSON_UNESCAPED_UNICODE);
                } else {
                    // 生成选项ID
                    $optionsWithIds = [];
                    foreach ($input['options'] as $optionText) {
                        $optionId = uniqid();
                        $optionsWithIds[$optionId] = $optionText;
                    }
                    
                    $options = json_encode($optionsWithIds, JSON_UNESCAPED_UNICODE);
                }
            }

            // 获取当前最大排序值
            $stmt = $this->conn->prepare("
                SELECT MAX(sort_order) as max_sort 
                FROM questions 
                WHERE questionnaire_id = :questionnaire_id
            ");
            $stmt->execute([':questionnaire_id' => $questionnaireId]);
            $maxSort = (int)$stmt->fetchColumn();

            // 插入问题
            $stmt = $this->conn->prepare("
                INSERT INTO questions (
                    questionnaire_id, type, content, tips, is_required, 
                    sort_order, options, is_name, is_date, created_at
                ) VALUES (
                    :questionnaire_id, :type, :content, :tips, :is_required,
                    :sort_order, :options, :is_name, :is_date, NOW()
                )
            ");
            $stmt->execute([
                ':questionnaire_id' => $questionnaireId,
                ':type' => $input['type'],
                ':content' => $input['content'] ?? null,
                ':tips' => $input['tips'] ?? null,
                ':is_required' => $input['is_required'] ?? true,
                ':sort_order' => $input['sort_order'] ?? ($maxSort + 1),
                ':options' => $options,
                ':is_name' => $input['is_name'] ?? 0,
                ':is_date' => $input['is_date'] ?? 0
            ]);
            $questionId = $this->conn->lastInsertId();

            echo json_encode([
                'code' => 200,
                'msg' => '问题添加成功',
                'data' => [
                    'id' => $questionId,
                    'type' => $input['type'],
                    'is_name' => $input['is_name'] ?? 0,
                    'is_date' => $input['is_date'] ?? 0
                ]
            ]);

        } catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * 更新问题（支持所有类型转换）
     */
    public function update(): void {
        try {
            $userId = $this->auth->getUserId();
            if ($userId === 0) {
                throw new Exception("请先登录", 401);
            }

            $input = json_decode(file_get_contents('php://input'), true);
            if ($input === null) {
                throw new Exception("无效的JSON数据", 400);
            }

            // 验证必填字段
            if (empty($input['id'])) {
                throw new Exception("缺少问题ID", 400);
            }
            if (empty($input['content'])) {
                throw new Exception("问题内容不能为空", 400);
            }

            $questionId = $input['id'];

            // 检查问题是否存在且属于当前用户
            $question = $this->getQuestion($questionId, $userId);
            if (!$question) {
                throw new Exception("问题不存在或无权操作", 404);
            }

            // 构建更新字段
            $updateFields = ["updated_at = NOW()"];
            $params = [':id' => $questionId];

            // 可更新字段（包括type、is_name和is_date）
            $allowedFields = ['content', 'tips', 'is_required', 'sort_order', 'type', 'is_name', 'is_date'];
            foreach ($allowedFields as $field) {
                if (isset($input[$field])) {
                    $updateFields[] = "{$field} = :{$field}";
                    $params[":{$field}"] = $input[$field];
                }
            }

            // 处理类型变更时的选项清理
            if (isset($input['type'])) {
                $newType = $input['type'];
                $oldType = $question['type'];
                
                // 如果从选择题改为文本类型，清除选项
                if (in_array($oldType, ['radio', 'check']) && in_array($newType, ['text', 'textarea'])) {
                    $updateFields[] = "options = NULL";
                }
                // 如果从文本类型改为选择题，初始化选项
                elseif (in_array($oldType, ['text', 'textarea']) && in_array($newType, ['radio', 'check'])) {
                    $updateFields[] = "options = :default_options";
                    $params[':default_options'] = json_encode(["A" => "选项1"]);
                }
                // 如果改为textgroup类型，初始化空数组
                elseif ($newType === 'textgroup') {
                    $updateFields[] = "options = :default_textgroup";
                    $params[':default_textgroup'] = json_encode([], JSON_UNESCAPED_UNICODE);
                }
            }

            // 更新选项（根据当前类型处理）
            if (isset($input['options'])) {
                if ($question['type'] === 'textgroup' || (isset($input['type']) && $input['type'] === 'textgroup')) {
                    // textgroup类型的options处理
                    if (is_string($input['options'])) {
                        $options = json_decode($input['options'], true);
                        if (json_last_error() !== JSON_ERROR_NONE) {
                            throw new Exception("文本组字段定义格式无效", 400);
                        }
                        $params[':options'] = $input['options']; // 保留原始JSON
                    } elseif (is_array($input['options'])) {
                        // 验证每个字段是否有label
                        foreach ($input['options'] as $field) {
                            if (empty($field['label'])) {
                                throw new Exception("文本组字段必须包含label属性", 400);
                            }
                        }
                        $params[':options'] = json_encode($input['options'], JSON_UNESCAPED_UNICODE);
                    } else {
                        throw new Exception("文本组字段定义必须是JSON字符串或数组", 400);
                    }
                    
                    $updateFields[] = "options = :options";
                } elseif ($question['type'] !== 'text' && $question['type'] !== 'textarea') {
                    // 选择题选项更新
                    if (is_string($input['options'])) {
                        $options = json_decode($input['options'], true);
                        if (json_last_error() !== JSON_ERROR_NONE) {
                            throw new Exception("选项格式无效", 400);
                        }
                        $params[':options'] = $input['options']; // 保留原始JSON
                    } elseif (is_array($input['options'])) {
                        $params[':options'] = json_encode($input['options'], JSON_UNESCAPED_UNICODE);
                    } else {
                        throw new Exception("选项格式必须是JSON字符串或数组", 400);
                    }
                    
                    $updateFields[] = "options = :options";
                }
            }

            if (count($updateFields) <= 1) {
                throw new Exception("没有可更新的字段", 400);
            }

            $sql = "UPDATE questions SET " . implode(', ', $updateFields) . " 
                    WHERE id = :id";
            
            $stmt = $this->conn->prepare($sql);
            $stmt->execute($params);

            echo json_encode([
                'code' => 200,
                'msg' => '问题更新成功',
                'data' => [
                    'type' => $input['type'] ?? $question['type'],
                    'is_name' => $input['is_name'] ?? $question['is_name'],
                    'is_date' => $input['is_date'] ?? $question['is_date']
                ]
            ]);

        } catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * 删除问题
     */
    public function delete(): void {
        try {
            $userId = $this->auth->getUserId();
            if ($userId === 0) {
                throw new Exception("请先登录", 401);
            }

            $input = json_decode(file_get_contents('php://input'), true);
            if ($input === null) {
                throw new Exception("无效的JSON数据", 400);
            }

            if (empty($input['id'])) {
                throw new Exception("缺少问题ID", 400);
            }

            $questionId = $input['id'];

            // 检查问题是否存在且属于当前用户
            $question = $this->getQuestion($questionId, $userId);
            if (!$question) {
                throw new Exception("问题不存在或无权操作", 404);
            }

            // 开始事务
            $this->conn->beginTransaction();

            try {
                // 删除问题回答
                $stmt = $this->conn->prepare("
                    DELETE FROM answer_details
                    WHERE question_id = :question_id
                ");
                $stmt->execute([':question_id' => $questionId]);

                // 删除问题
                $stmt = $this->conn->prepare("
                    DELETE FROM questions
                    WHERE id = :id
                ");
                $stmt->execute([':id' => $questionId]);

                $this->conn->commit();

                echo json_encode([
                    'code' => 200,
                    'msg' => '问题删除成功'
                ]);

            } catch (Exception $e) {
                $this->conn->rollBack();
                throw new Exception("删除问题失败: " . $e->getMessage(), 500);
            }

        } catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * 问题排序
     */
    public function sort(): void {
        try {
            $userId = $this->auth->getUserId();
            if ($userId === 0) {
                throw new Exception("请先登录", 401);
            }

            $input = json_decode(file_get_contents('php://input'), true);
            if ($input === null) {
                throw new Exception("无效的JSON数据", 400);
            }

            // 验证必填字段
            if (empty($input['q_id'])) {
                throw new Exception("缺少问卷ID", 400);
            }
            if (empty($input['order']) || !is_array($input['order'])) {
                throw new Exception("缺少排序数据", 400);
            }

            $questionnaireId = $input['q_id'];

            // 检查问卷是否存在且属于当前用户
            $stmt = $this->conn->prepare("
                SELECT id FROM questionnaires 
                WHERE id = :id AND user_id = :user_id
                LIMIT 1
            ");
            $stmt->execute([
                ':id' => $questionnaireId,
                ':user_id' => $userId
            ]);
            if (!$stmt->fetch()) {
                throw new Exception("问卷不存在或无权操作", 404);
            }

            // 开始事务
            $this->conn->beginTransaction();

            try {
                // 更新排序
                foreach ($input['order'] as $index => $questionId) {
                    $stmt = $this->conn->prepare("
                        UPDATE questions 
                        SET sort_order = :sort_order
                        WHERE id = :id AND questionnaire_id = :questionnaire_id
                    ");
                    $stmt->execute([
                        ':sort_order' => $index + 1,
                        ':id' => $questionId,
                        ':questionnaire_id' => $questionnaireId
                    ]);
                }

                $this->conn->commit();

                echo json_encode([
                    'code' => 200,
                    'msg' => '问题排序更新成功'
                ]);

            } catch (Exception $e) {
                $this->conn->rollBack();
                throw new Exception("更新排序失败: " . $e->getMessage(), 500);
            }

        } catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * 获取问题详情（内部方法）
     */
    private function getQuestion(int $id, int $userId): ?array {
        $stmt = $this->conn->prepare("
            SELECT q.*
            FROM questions q
            JOIN questionnaires qn ON q.questionnaire_id = qn.id
            WHERE q.id = :id AND (qn.user_id = :user_id OR qn.is_template = 1)
            LIMIT 1
        ");
        $stmt->execute([
            ':id' => $id,
            ':user_id' => $userId
        ]);
        $question = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($question) {
            // 格式化选项
            if ($question['options']) {
                $question['options'] = json_decode($question['options'], true);
            }
            
            // 为textgroup类型设置默认值
            if ($question['type'] === 'textgroup' && empty($question['options'])) {
                $question['options'] = [];
            }
            
            // 确保is_name和is_date有默认值
            $question['is_name'] = $question['is_name'] ?? 0;
            $question['is_date'] = $question['is_date'] ?? 0;
        }
        
        return $question ?: null;
    }
}